文章目录
  1. 1. k8s 自定义controller
    1. 1.1. CRD Controller的开发逻辑
      1. 1.1.1. 那 KubeBuilder 原理呢?
    2. 1.2. CRD Controller 开发环境搭建
    3. 1.3. 安装kubeBuilder
    4. 1.4. 使用kubebuilder生成controller+crd模板
      1. 1.4.1. 生成架构代码
    5. 1.5. 创建CRD
    6. 1.6. 安装CRD到集群
    7. 1.7. 启动控制器
    8. 1.8. 编写自定义controller逻辑代码

k8s 自定义controller

CRD Controller的开发逻辑

控制器的目的是让 CRD 定义的资源达到我们预期的一个状态,要达到我们定义的状态,我们需要监听触发事件。触发事件的概念是从硬件信号产生 中断 的机制衍生过来的,
其产生一个电平信号时,有水平触发(包括高电平、低电平),也有边缘触发(包括上升沿、下降沿触发等)。

  • 水平触发 : 系统仅依赖于当前状态。即使系统错过了某个事件(可能因为故障挂掉了),当它恢复时,依然可以通过查看信号的当前状态来做出正确的响应。
  • 边缘触发 : 系统不仅依赖于当前状态,还依赖于过去的状态。如果系统错过了某个事件(“边缘”),则必须重新查看该事件才能恢复系统。

Kubernetes 的 API 和控制器都是基于水平触发的,可以促进系统的自我修复和周期调协。
其 API 实现方式(也是我们常说的声明式 API)是:控制器监视资源对象的实际状态,并与对象期望的状态进行对比,然后调整实际状态,使之与期望状态相匹配。

那 KubeBuilder 原理呢?

它的控制器实现的接口是 Reconcile 方法,该方法要求控制器的实现逻辑是基于水平触发的, 实现方不能假定每一次的对象的变更都会触发一次 Reconcile。KubeBuilder 为性能考虑会合并同一个对象的修改请求,这要求使用方不考虑中间的执行步骤,以面向终态的方式来实现业务逻辑。具体来说每次资源 Status 状态的构建都不能依赖过去的值,要求能够完全根据目前的环境的查询来构建值。

CRD Controller 开发环境搭建

我们创建了CRD,再通过自动生成代码的工具将controller所需的informer、client等依赖全部准备好,到了本章,就该编写controller的代码了,也就是说,现在已经能监听到Student对象的增删改等事件,接下来就是根据这些事件来做不同的事情,满足个性化的业务需求;

controller的作用就是监听指定对象的新增、删除、修改等变化,针对这些变化做出相应的响应(例如新增pod的响应为创建docker容器),关于controller的详细设计,最好的参考就是Harry (Lei) Zhang老师在twitter上的分享,如下图,地址是:https://twitter.com/resouer/status/1009996649832185856

原理:

在这里插入图片描述

如上图,API对象的变化会通过Informer存入队列(WorkQueue),在Controller中消费队列的数据做出响应,响应相关的具体代码就是我们要做的真正业务逻辑;

https://book.kubebuilder.io/introduction.html

使用 KubeBuilder v2 版本,该框架可以方便的生成符合 K8S 规范的 CRD 文件和对应的 Controller 代码,我们只需要实现其调协逻辑即可。

安装kubeBuilder

安装kubeBuilder的必要条件:

  • go version v1.13+.
  • docker version 17.03+.
  • kubectl version v1.11.3+.
  • Access to a Kubernetes v1.11.3+ cluster.

我使用的是mac os,当前的go版本是v1.12,需要升级,由于升级太麻烦了,我之前是通过homebrew安装的,所以我直接卸载掉,从官网上下载最新的go版本,直接安装:

tval.sinaimg

现在已经满足了安装kubebuilder的要求了。

官方文档是这样安装的:

os=$(go env GOOS)
arch=$(go env GOARCH)

# download kubebuilder and extract it to tmp
curl -L https://go.kubebuilder.io/dl/2.3.1/${os}/${arch} | tar -xz -C /tmp/

# move to a long-term location and put it on your path
# (you'll need to set the KUBEBUILDER_ASSETS env var if you put it somewhere else)
sudo mv /tmp/kubebuilder_2.3.1_${os}_${arch} /usr/local/kubebuilder
export PATH=$PATH:/usr/local/kubebuilder/bin

但我电脑上好像无法这样安装,只能通过这样安装:

os=$(go env GOOS) 

arch=$(go env GOARCH)

wget https://go.kubebuilder.io/dl/latest/${os}/${arch}

tar -xzvf kubebuilder_master_darwin_amd64.tar.gz -C /tmp/

sudo mv /tmp/kubebuilder_master_darwin_amd64 /usr/local/kubebuilder

export PATH=$PATH:/usr/local/kubebuilder/bin

使环境变量永久生效,加入到.bash_profile, vi ~/.bash_profile

​ export PATH=$PATH:/usr/local/kubebuilder/bin

source ~/.bash_profile

检查kubebuilder是否安装成功:

image-20210219141047307

发现已经安装成功了!!!

使用kubebuilder生成controller+crd模板

kubebuilder官网生成controller模板:

https://github.com/kubernetes-sigs/kubebuilder

生成架构代码

有两种方法,一种是采用 GOPATH,另一种是 go mod

官方建议:

If you’re not in GOPATH, you’ll need to run go mod init <modulename> in order to tell kubebuilder and Go the base import path of your module.

我电脑上也没配置GOPATH,所以我只能通过go mod 方式。

一般不建议通过在GOPATH目录下新建项目,所以我使用go mod方式生成架构代码:

因为墙的原因,需要设置go的代理:export GOPROXY=https://goproxy.cn ,否则kubebuilder init时会timeout

  1. mkdir test1 && go mod init my.domain

    返回: go: creating new go.mod: module my.domain

  2. kubebuilder init –domain my.domain

返回如下信息:

image-20210219145732228

初始化项目完成!!

现在我们只生成了第一步的代码,我们先来看看这部分代码是否能运行及其效果如何?

这时需要保证你的终端能访问 K8S 的测试集群,简单就是用 kubectl cluster-info 看看是否出错,如果不出错,就可以 go run main.go

image-20210219153552962

由以上图片可以看出,集群是正常运行的。

现在我们执行一下 go run main.go返回:

image-20210219153755319

从以上图片返回的结果可以看出,其实 KubeBuilder 帮我们生成一个管理 Controller 的 Manager 的代码(controller-runtime.manager),但是还没添加 Controller

创建CRD

创建一个名为Guestbook的CRD, 路径为webapp/v1:

kubebuilder create api --group webapp --version v1 --kind Guestbook

执行后报错了:

image-20210219164317707

是不是由于我安装的kubeBuilder版本是master版本,对应的k8s版本是1.16.4的原因?

经过不断的探索,发现是由于我k8s的api server所支持的go版本是v1.13.5:

image-20210219175237674

将最新的1.16版本卸载,安装1.13.5这个版本

再次执行:

kubebuilder create api --group webapp --version v1 --kind Guestbook

返回成功:

image-20210219180344798

这里简单注意一下, group / version / kind 这三个属性组合起来来标识一个 K8S 的 CRD。另外就是 kind 要首字母大写而且不能有特殊符号

成功建立了一个自定义crd了,但是内容是空的,没做任何事。。。。

安装CRD到集群

make install

又报错了:

image-20210219180834671

是因为没有安装kustomize,那我安装一个:

bwi kustomize

再次执行,返回成功:

image-20210219181048285

查看一下,是否安装成功:

image-20210219181149669

此时已经将 CRD 安装到集群了。

启动控制器

使用make run 命令启动控制器:

image-20210219184647486

编写自定义controller逻辑代码

参考此文章

https://www.cnblogs.com/alisystemsoftware/p/11580202.html

文章目录
  1. 1. k8s 自定义controller
    1. 1.1. CRD Controller的开发逻辑
      1. 1.1.1. 那 KubeBuilder 原理呢?
    2. 1.2. CRD Controller 开发环境搭建
    3. 1.3. 安装kubeBuilder
    4. 1.4. 使用kubebuilder生成controller+crd模板
      1. 1.4.1. 生成架构代码
    5. 1.5. 创建CRD
    6. 1.6. 安装CRD到集群
    7. 1.7. 启动控制器
    8. 1.8. 编写自定义controller逻辑代码